package com.xyh.concurrency.example.commonUnsafe;


import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Vector;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Semaphore;

import com.xyh.concurrency.annoations.ThreadSafe;

import lombok.extern.slf4j.Slf4j;

/**
 * 线程安全类
 *
 * @author yihang.xu
 */
@Slf4j
@ThreadSafe
public class ArreyListExamlpe1 {
    //创建初始化新线程
    private static int clientTotal = 5000;
    //允许并发的线程数
    private static int threadTotal = 200;
    private static String string = "";
    /**
     * 使用 Vector 解决线程不安全的问题
     * <p>
     * Vector 和 Collections 创建出的list都是线程安全的
     */

    private static List<Integer> list = new Vector<>();
    private static List<Integer> sychonizebLsit = Collections.synchronizedList(new ArrayList<Integer>());

    public static void main(String[] args) throws InterruptedException {

        //创建线程池
        ExecutorService executorService = Executors.newCachedThreadPool();
        //创建并发允许额数量
        final Semaphore semaphore = new Semaphore(threadTotal);
        //最大线程数
        CountDownLatch countDownLatch = new CountDownLatch(clientTotal);
        for (int i = 0; i < clientTotal; i++) {
            final int cunt = i;
            executorService.execute(() -> {
                try {
                    //开启线程阻塞
                    semaphore.acquire();
                    update(cunt);
                    //关闭线程阻塞,释放后钱200 线程
                    semaphore.release();
                } catch (Exception ex) {
                    log.error("name", ex.toString());
                }
                countDownLatch.countDown();
            });

        }

        countDownLatch.await();
        executorService.shutdown();
        log.info("cpunt:{}", list.size());

    }

    public static void update(int i) {
        list.add(i);
        sychonizebLsit.add(i);
        int size = sychonizebLsit.size();

        if (size >= 5000) {
            System.out.println(size);
        }
    }
}
